iT邦幫忙

2026 iThome 鐵人賽

DAY 1
0
Software Development

遠古聖遺物改造工程:遺留系統全面重構實務指南系列 第 1

[Day 01] 甚麼是遺留系統?為甚麼需要重構?

  • 分享至 

  • xImage
  •  

甚麼是遺留系統(Legacy System)?

遺留系統是指具有 「系統架構不清晰」「難以維護及修改」「缺乏測試流程」「難以遷移及部署」 等性質的系統。這類系統或許仍然運作,累積了長期使用形成的規則。但卻因為團隊缺乏規範與管理,使得系統在長時間的維護修改下,整體架構變得複雜、高度耦合,進而導致難以維護。為了讓系統能夠繼續使用,則需要 「全面重構」 遺留系統。

遺留系統的特徵

遺留系統往往不是由單一問題造成,而是由許多小問題日積月累造成的結果。其中常見的特徵包括:

相同規則重複實作

多個功能可能需要執行相同的處理流程,但各自保留獨立的實作。當這項共同邏輯需要調整時,必須同步修改所有實作。如果遺漏其中一處,可能會造成不同功能產生不一致的結果。

例子
描述:某個系統提供數十個 API,每個 API 都各自實作相同的存取憑證驗證流程。
變更:驗證流程新增憑證期限檢查。
結果:部分介面遺漏修改,仍接受已失效的憑證。

資料高度耦合

程式中的不同處理邏輯如果直接依賴相同資料的結構、格式或欄位意義,就會出現 「資料高度耦合」 的情況。當資料的結構或表示方式改變時,所有相關處理邏輯都必須同步調整。這會擴大變更範圍,也容易遺漏修改。

例子
描述:某個資料查詢 API 會將資料表中所有欄位以陣列格式回傳,目前程式透過索引值讀取指定欄位的值。
變更:資料表在原有欄位之間加入新的欄位,使 API 回傳陣列中後續欄位的索引值改變。
結果:未同步修改的程式仍從原有索引位置讀取資料,因而取得錯誤欄位的值。

缺乏規範的測試、建置、部署流程

測試、建置與部署流程如果沒有明確且可重複執行的步驟,每次變更難以使用相同方式確認結果。執行方式依賴人工記憶或個別環境時,容易遺漏必要步驟,也無法確認每次產生的成品是否一致。

例子
描述:團隊以人工步驟測試與建置系統程式,再將產生的檔案部署到執行環境。
變更:系統程式新增一個相依函式庫,部署時需要同時複製對應檔案。
結果:部分人員仍沿用舊步驟,部署的系統程式缺少必要檔案而無法啟動。

缺少可靠的文件,依賴特定人員

系統知識如果沒有透過可靠文件記錄,可能只存在少數人員的記憶中。當文件缺失、過時或與實際行為不一致時,其他人員就需要重新探索系統或反覆詢問熟悉系統的人員,增加理解與修改程式所需的時間。

例子
描述:系統部署時需要將特定目錄掛載至指定路徑,但這項設定沒有記錄在文件中,只有原開發人員知道。
變更:原開發人員離開團隊,其他人員需要將系統部署到其他機器上。
結果:接手人員未掛載該目錄,系統無法取得執行所需的檔案,因此無法啟動。

技術與執行環境逐漸淘汰

系統長期未更新時,可能依賴已停止支援的程式語言版本、函式庫、作業系統。當這些相依項目無法繼續取得修正或替代時,系統可能無法在新的執行環境中運作,也會增加維護與復原的難度。

例子
描述:系統程式依賴已停止支援的程式語言版本與函式庫。
變更:團隊將建置環境更新至仍受支援的程式語言版本,並替換停止維護的函式庫。
結果:原有程式因語法與函式庫介面不相容而無法完成建置,必須調整程式後才能部署。

為什麼需要重構?

重構(Refactor)是改善軟體內部結構,同時維持既有外部行為的工程活動。重構的重點在於處理系統長期累積的技術債,改善系統的可維護性,並降低理解、修改、測試與部署系統的成本。

降低功能變更的風險

遺留系統的程式結構如果缺乏清楚的責任範圍,一項功能變更可能同時影響多個處理流程。重構可以重新安排程式責任與相依關係,讓變更集中在明確範圍,降低遺漏修改或影響其他功能的機率。

例子
描述:某個系統的數十個 API 各自實作相同的存取憑證驗證流程。新增憑證期限檢查時,部分 API 曾因遺漏修改而仍接受已失效的憑證。
變更:重構將存取憑證驗證集中為共用流程,並由所有 API 統一呼叫。
結果:後續調整驗證規則時只需要修改共用流程,所有 API 都會套用相同規則,降低遺漏修改的風險。

提高開發與維護效率

程式碼結構混亂時,開發人員需要花費額外時間尋找功能的實作位置與相依關係。重構可以改善命名、拆分過長的處理流程並移除重複程式,讓開發人員更容易理解及修改程式。

例子
描述:系統使用一個功能複雜、牽涉多個流程的函式。
變更:重構將不同處理拆分為名稱與責任明確的函式。
結果:開發人員可以直接找到需要修改的函式,不必反覆閱讀整段程式。

保留系統知識並降低人員風險

遺留系統可能包含特殊規則、架構或操作方法,但只有少數人員掌握其目的與執行方式。重構後可以透過清楚的程式結構、測試與文件記錄這些知識,讓其他開發人員也能理解及維護系統,降低系統對特定人員的依賴。

例子
描述:系統部署時需要將特定目錄掛載至指定路徑,但這項設定沒有記錄在文件中,只有原開發人員知道。
變更:重構時將目錄用途、掛載路徑與操作步驟記錄在部署文件中,並加入啟動檢查確認目錄是否正確掛載。
結果:其他人員可以依照文件完成設定,系統也能在目錄未掛載時提供明確的錯誤訊息,不再需要依賴原開發人員完成部署。

改善測試與部署能力

程式如果直接包含特定執行環境的設定,測試與部署前可能需要人工修改程式。重構可以將執行設定與程式邏輯分開,使相同的系統程式能在不同環境中接受測試與部署。

例子
描述:系統程式將資料路徑直接寫在程式碼中,測試與部署前都需要人工修改路徑。
變更:重構將資料路徑改為由執行設定提供,測試與部署使用各自的設定。
結果:團隊可以使用相同的系統程式執行測試與部署,避免人工修改程式造成差異。

降低技術債的長期成本

技術債會使原本單純的功能變更需要額外處理重複程式、不清楚的相依關係或例外流程。重構可以改善這些設計與實作問題,避免團隊在後續修改中持續付出相同成本。

例子
描述:系統中的多個功能直接使用已停止維護的函式庫,而且各自採用不同的呼叫方式。
變更:重構建立共用流程集中使用該函式庫,並將相依項目替換為仍受支援的版本。
結果:後續更新相依項目時只需要調整共用流程,減少重複修改各項功能的成本。

一定要重構嗎?甚麼時候可以不重構?

不是所有遺留系統都值得重構。判斷是否需要重構時,應同時考慮系統的 「使用價值」「變更頻率」「維護成本」「風險與替代方案」。以下情況可以考慮不重構:

  • 系統即將被替換或正式停用,剩餘使用期間很短。
  • 系統使用頻率低、影響範圍小,維護成本仍在可接受範圍內。
  • 系統雖然技術老舊,但功能穩定、很少變更,且沒有明顯安全或法規上的風險。
  • 重構成本遠高於系統持續提供的使用價值。
  • 團隊目前尚未具備測試、部署、版本還原的基本能力,大幅修改可能增加正式環境的風險。

但不重構不代表可以不處理系統當前面對的問題。應該先建立最低限度的文件、備份、監控與操作手冊,並記錄未來需要處理的風險。如果系統仍持續提供重要功能,應該定期重新評估重構系統的可行性。

本系列所稱的「全面重構」,是根據既有系統行為重新設計並建置目標系統,同時調整架構、資料模型與功能。後續將從需求與範圍開始,依序討論如何分析既有系統、保護與遷移資料、建置目標系統、執行整體測試、規劃正式切換,以及透過監控與文件降低系統啟用後的風險。

重點整理

  • 遺留系統具有系統架構不清晰、難以維護及修改、缺乏測試流程、難以遷移及部署等性質,長期維護可能使架構變得複雜且高度耦合。
  • 遺留系統的常見特徵包括相同規則重複實作、資料高度耦合、測試、建置與部署流程缺乏規範、文件不足並依賴特定人員,以及技術與執行環境逐漸淘汰。
  • 重構用來改善軟體內部結構、處理系統長期累積的技術債、提高可維護性,並降低理解、修改、測試與部署系統的成本。
  • 重構可以降低功能變更的風險、提高開發與維護效率、保留系統知識、改善測試與部署能力,並降低技術債的長期成本。
  • 團隊應根據系統的使用價值、變更頻率、維護成本、風險、替代方案與現有能力判斷是否重構。如果決定不重構,仍應建立最低限度的文件、備份、監控與操作手冊,並定期重新評估重構的可行性。
  • 本系列所稱的全面重構,是根據既有系統行為重新設計並建置目標系統,同時調整架構、資料模型與功能。

系列文
遠古聖遺物改造工程:遺留系統全面重構實務指南1
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言